﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
using System.Web;
using System.Web.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
using System.Web.Http.Results;

namespace NCS.IConnect.Core.WebApi
{
    /// <summary>
    /// A custom <see cref="IActionFilter"/> to make sure the If-Match header of request contains a valid version no.
    /// </summary>
    [ComVisible(false)]
    public class EnsureVersionNoExistsAttribute : ActionFilterAttribute
    {       
        /// <summary>
        ///  Occurs before the action method is invoked.
        /// </summary>
        /// <param name="actionContext">The action context.</param>
        [EnvironmentPermission(SecurityAction.LinkDemand, Unrestricted = true)]
        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            HttpConfiguration configuration = actionContext.Request.GetConfiguration();
            var negotiator = configuration.Services.GetContentNegotiator();
            var negotiationResult = negotiator.Negotiate(typeof(ServiceExceptionDetail), actionContext.Request, configuration.Formatters);

            ReflectedHttpActionDescriptor actionDescriptor = (ReflectedHttpActionDescriptor)actionContext.ActionDescriptor;
            int versionNo = -1;
            if (!actionContext.Request.Headers.IfMatch.Any())
            {
                HttpResponseMessage responseMessage = new HttpResponseMessage(HttpStatusCode.PreconditionFailed);
                responseMessage.Content = new ObjectContent<ErrorInfo>(Errors.E0001, negotiationResult.Formatter);
                actionContext.Response = responseMessage;
                return;
            }
            if (!int.TryParse(actionContext.Request.Headers.IfMatch.First().Tag.Trim('"'), out versionNo))
            {
                HttpResponseMessage responseMessage = new HttpResponseMessage(HttpStatusCode.PreconditionFailed);
                responseMessage.Content = new ObjectContent<ErrorInfo>(Errors.E0002, negotiationResult.Formatter);
                actionContext.Response = responseMessage;
                return;
            }
        }
    }
}